/*
 * @Author: EvanXU evanxu8023@163.com
 * @Date: 2023-02-04 11:02:16
 * @LastEditors: Evanxu-home evanxu8023@163.com
 * @LastEditTime: 2025-11-15 16:09:34
 * @FilePath: \program\applications\user_memory.c
 * @Description: 
 *  xxx 
 * Copyright (c) 2023 by EvanXU evanxu8023@163.com, All Rights Reserved. 
 */
#include "user_memory.h"

#undef	LOG_LVL
#define LOG_LVL		LOG_LVL_DEBUG
#include "log.h"

/* 用户系统设置参数 */
USER_MEMORY sys_user_memory;
/* 系统运行默认配置参数 */
USER_MEMORY mem_default = USER_MEMORY_DEFAULT;

/**
 * @description: 获取用户系统配置参数(只包含系统运行参数)
 * @return {*}
 */
int read_user_config_para(void)
{
    /* 系统运行默认配置参数 */
//    USER_MEMORY mem_default = USER_MEMORY_DEFAULT;
    uint32_t crc = 0;
    int res = 0;
    /* 从MCU FLASH读取数据 */
    flash_read(USER_MEMORY_START_ADDR, (uint16_t *)(&sys_user_memory), sizeof(USER_MEMORY) / 2);
    /* 检查CRC */    
    crc = user_memory_para_crc_check((uint32_t *)(&sys_user_memory), sizeof(USER_MEMORY) / 4  - 1);
    log_d("old_head = 0x%08X, old_crc = 0x%04X",sys_user_memory.head, sys_user_memory.crc);
	
    /* 检查包头以及数据包CRC结果 */
    if(sys_user_memory.crc == crc  &&  sys_user_memory.head == USER_MEMEORY_DATA_HEAD)
	{
		log_i("find user memory package head.");
	}
	else
	{
		log_e("use default data package.");
		/* 将默认数据拷贝至缓存 */
		memcpy((uint8_t *)&sys_user_memory, (uint8_t *)&mem_default, sizeof(USER_MEMORY));
		crc = user_memory_para_crc_check((uint32_t *)(&sys_user_memory), sizeof(USER_MEMORY) / 4  - 1);
		sys_user_memory.crc = crc;
        /* 写入默认数据 */
        flash_write_nocheck(USER_MEMORY_START_ADDR, (uint16_t *)(&sys_user_memory), sizeof(USER_MEMORY) / 2);
        res = 1;
	}
    /* 打印相关数据 */
	log_i("now_head = 0x%08X, now_crc = 0x%08X, sizeof(USER_MEMORY) = %d", sys_user_memory.head, crc, sizeof(USER_MEMORY));
	log_d(".cfg_para.rgb_length = %u", sys_user_memory.cfg_para.rgb_length);
	log_d(".cfg_para.flow_time = %u", sys_user_memory.cfg_para.flow_time);
	log_d(".cfg_para.all_on_time = %u", sys_user_memory.cfg_para.all_on_time);
    log_d(".cfg_para.rgb_bright = %u", sys_user_memory.cfg_para.rgb_bright);
    log_d(".cfg_para.rgb_format = %u", sys_user_memory.cfg_para.rgb_format);

    return res;
}

/**
 * @description: 写用户运行参数
 * @param {user_mem} *buff 用户配置参数指针
 * @return {*}
 */
void write_user_config_para(USER_MEMORY *buff)
{
	if(buff != NULL)
	{
		if(buff->head == USER_MEMEORY_DATA_HEAD)
        {
            buff->crc = user_memory_para_crc_check((uint32_t *)buff, sizeof(USER_MEMORY) / 4  - 1);
            flash_write_nocheck(USER_MEMORY_START_ADDR, (uint16_t *)(buff), sizeof(USER_MEMORY) / 2);
        }
		else
		{
        	log_e("data package head error.");
        }
	}
}

/**
 * @description: 重置用户运行参数为出厂默认
 * @param {user_mem} *buff 用户配置参数指针
 * @return {*}
 */
void reset_user_config_para(void)
{
    uint32_t crc = 0;
    
    /* 将默认数据拷贝至缓存 */
    memcpy((uint8_t *)&sys_user_memory, (uint8_t *)&mem_default, sizeof(USER_MEMORY));
    crc = user_memory_para_crc_check((uint32_t *)(&sys_user_memory), sizeof(USER_MEMORY) / 4  - 1);
    sys_user_memory.crc = crc;
    /* 写入默认数据 */
    flash_write_nocheck(USER_MEMORY_START_ADDR, (uint16_t *)(&sys_user_memory), sizeof(USER_MEMORY) / 2);
}


/**
 * @description:        用户保存参数CRC校验(按字节进行和校验)
 * @param {u8} *buff    数据指针
 * @return {*}          32bit crc和校验数值
 */
uint32_t user_memory_para_crc_check(uint32_t *buff, uint32_t len)
{
    uint32_t i = 0, crc = 0;

    for(i=0; i<len; i++)
        crc += *buff++;

    return (crc^0x1234);
}
